package cn.waka.sys.admin.controller;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.out;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.waka.sys.admin.object.WechatConfig;
import cn.waka.sys.admin.service.WechatConfigService;
import cn.waka.sys.admin.utils.SignUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

@RequestMapping("/wechat1")
@Controller
public class WechatController extends BaseController {

    String host="http://wkt.naiba100.com/";
    String appid="wxd8a133a0a2fee000";
    String secret="5ae06b919e63c11efbdd2fe42a9a55ce";
    //String appid="wx321b1a1321a9dfbf";
    //String secret="87e98af02a056fef5910bca6aab456ae";
    String grant_type="authorization_code";
    String accessToken="15_suxDZSvY_jJ90pbva0QE-cKeUZ4wesf_CBvutSF8O89VEwENQV0cN8WxpeVKgs3erdh1AvWyDVVvJ3DgI-Dusd_xr9Y8NUfG1eFhOTqi_-H8v4B2iq75yvP9iXCjmjEUxYrfL_-aKk0KZi5hIMSgAIABFL";
    OkHttpClient client=new OkHttpClient();
    ObjectMapper mapper=new ObjectMapper();
    protected WxMpInMemoryConfigStorage config;
    protected WxMpService wxMpService;
    protected WxMpMessageRouter wxMpMessageRouter;
    String token="fb0341ebd70d4a6673d54a68b7403795";

    public void setService(WechatConfigService service) {
        this.service = service;
    }

    @Autowired
    private WechatConfigService service;


    @RequestMapping(value = "config1/{appid}",produces = "application/xml")
    public void index1(@PathVariable(value="appid",required = false) String appid,String signature,String timestamp,String nonce, HttpServletRequest request, HttpServletResponse response)  {

        if(appid==null||signature==null||timestamp==null||nonce==null){
            return;
        }

        String echostr = request.getParameter("echostr");

        out.println("====appid:"+appid);
        WechatConfig config=service.findById(appid);
        if(echostr!=null){

            if(config==null){
                return;
            }
            boolean flag = SignUtil.checkSignature(config, signature, timestamp,nonce);
        }

        if("POST".equals(request.getMethod())) {

            String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
                    "raw" :
                    request.getParameter("encrypt_type");
            out.println("========EncryptType:" + encryptType);
            if ("raw".equals(encryptType)) {

                // 明文传输的消息
                try {
                    InputStream is = request.getInputStream();
                    if (is.available() > 0) {
                        WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(is);
                        out.println("====event:" + inMessage.getEvent()+" key:"+inMessage.getEventKey());
                        out.println("====post:" + inMessage.getContent());
                        WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
                        if (outMessage == null) {
                            //为null，说明路由配置有问题，需要注意
                            response.getWriter().write("");
                            return;
                        }
                        response.getWriter().write(outMessage.toXml());
                        return;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                //return;
            }
        }
        boolean flag = SignUtil.checkSignature(config, signature, timestamp,nonce);
        out.println("nonce="+nonce+"&echostr="+echostr+"&timestamp="+timestamp +"&signature="+signature );
        out.println(currentTimeMillis() + "时:Token验证成功");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/plain; charset=UTF-8");
        try {
            if(echostr!=null&&echostr.length()>0) {
                response.getWriter().write(echostr);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
       // response.getWriter().flush();
        /*if (flag) {
            try {
                // &#x9a8c;&#x8bc1;&#x6210;&#x529f;,&#x5219;&#x539f;&#x6837;&#x8fd4;&#x56de;echostr&#x53c2;&#x6570;&#x5185;&#x5bb9;
                System.out.println("nonce="+nonce+"&echostr="+echostr+"&timestamp="+timestamp +"&signature="+signature );
                System.out.println(System.currentTimeMillis() + "&#x65f6;:Token&#x9a8c;&#x8bc1;&#x6210;&#x529f;");
                return echostr;
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        return "success";*/
    }


    @RequestMapping(value = "index1")
    public void index(HttpServletRequest request, HttpServletResponse response)  {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");


        //out.println("====post:"+body);

        String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
                "raw" :
                request.getParameter("encrypt_type");


        //boolean flag = SignUtil.checkSignature(token, signature, timestamp,nonce);
        out.println("nonce="+nonce+"&echostr="+echostr+"&timestamp="+timestamp +"&signature="+signature );
        out.println(currentTimeMillis() + "时:Token验证成功");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/plain; charset=UTF-8");
        try {
            if(echostr!=null&&echostr.length()>0) {
                response.getWriter().write(echostr);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        // response.getWriter().flush();
        /*if (flag) {
            try {
                // &#x9a8c;&#x8bc1;&#x6210;&#x529f;,&#x5219;&#x539f;&#x6837;&#x8fd4;&#x56de;echostr&#x53c2;&#x6570;&#x5185;&#x5bb9;
                System.out.println("nonce="+nonce+"&echostr="+echostr+"&timestamp="+timestamp +"&signature="+signature );
                System.out.println(System.currentTimeMillis() + "&#x65f6;:Token&#x9a8c;&#x8bc1;&#x6210;&#x529f;");
                return echostr;
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        return "success";*/
    }


    @RequestMapping("code")
    public void code(HttpServletRequest request,HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        try {
            String redirect_uri= URLEncoder.encode(host+"wechat/user", "UTF-8");
            StringBuffer url=new StringBuffer("https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid+"&redirect_uri="+redirect_uri+
                    "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect");
            out.println("====url:"+url);
            response.sendRedirect(url.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @RequestMapping("user")
    public void user(HttpServletRequest request,HttpServletResponse response) throws IOException {
        response.setContentType("text/html");

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String code = request.getParameter("code");//获取code
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&grant_type="+grant_type+"&code="+code;
        String res=require(url);
        ObjectMapper mapper=new ObjectMapper();
        Map<String,String> rs = mapper.readValue(res, HashMap.class);
        String openid=rs.get("openid");
        String encode=new String(Base64Utils.encode(openid.getBytes()));
        out.println("======userinfo:"+res);
        out.println("===openid base64 encode:"+encode);
        String decode=new String(Base64Utils.decode(encode.getBytes()));
        out.println("===openid base64 decode:"+decode);
        String url1="https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openid;
        String rs1=require(url1);
        out.println("===用户信息："+rs1);
        response.getWriter().write(openid);


       /* String result = HttpGetUtil.httpRequestToString(
                "https://api.weixin.qq.com/sns/oauth2/access_token", params);
        JSONObject jsonObject = JSONObject.fromObject(result);

        String openid = jsonObject.get("openid").toString();
        System.out.println("得到的openid为:"+openid);*/
    }

    @RequestMapping("token")
    public void token(HttpServletResponse response){
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
        String rs=require(url);
        ObjectMapper mapper=new ObjectMapper();
        try {
            Map<String, String> map = mapper.readValue(rs, HashMap.class);
            accessToken=map.get("access_token");
            out.println("=========token:"+accessToken);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }

    //@PostConstruct
    public void init(){

        config = new WxMpInMemoryConfigStorage();
        config.setAppId(appid); // 设置微信公众号的appid
        config.setSecret(secret); // 设置微信公众号的app corpSecret
        config.setToken("test"); // 设置微信公众号的token



        wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(config);

        WxMpMessageHandler handler = new WxMpMessageHandler() {
            @Override
            public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
                WxMpXmlOutTextMessage m
                        = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUser())
                        .toUser(wxMessage.getFromUser()).build();
                return m;
            }
        };

        wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
        wxMpMessageRouter
                .rule()
                .async(false)
                //.content("哈哈") // 拦截内容为“哈哈”的消息
                .handler(handler)
                .end();




    String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
        String res=require(url);
        ObjectMapper mapper=new ObjectMapper();
        try {
            Map<String, String> map = mapper.readValue(res, HashMap.class);
            accessToken=map.get("access_token");
            out.println("=========token:"+accessToken);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }
    @RequestMapping("menu")
    public void menu(HttpServletResponse response){
        String url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+accessToken;
        String menus=" {" +
                "     \"button\":[" +
                "     {    " +
                "          \"type\":\"click\"," +
                "          \"name\":\"今日歌曲\"," +
                "          \"key\":\"V1001_TODAY_MUSIC\"" +
                "      }," +
                "      {" +
                "           \"name\":\"菜单\"," +
                "           \"sub_button\":[" +
                "           {    " +
                "               \"type\":\"view\"," +
                "               \"name\":\"搜索\"," +
                "               \"url\":\"http://www.soso.com/\"" +
                "            }," +
                "            {" +
                "               \"type\":\"click\"," +
                "               \"name\":\"赞一下我们\"," +
                "               \"key\":\"V1001_GOOD\"" +
                "            }]" +
                "       }]" +
                " }";
        String rs=require(url,menus);
        try {
            response.getWriter().write(rs);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("industry")
    public void industry(HttpServletResponse response){
        String url="https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token="+accessToken;

        String content=" {\n" +
                "          \"industry_id1\":\"1\",\n" +
                "          \"industry_id2\":\"12\"\n" +
                "       }";
        String res=this.require(url,content);
        out.println("=======设置行业："+res);
        try {
            response.getWriter().write(res);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @RequestMapping("templete")
    public void templete(HttpServletResponse response){
        String url="https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token="+accessToken;
        String res=this.require(url);
        out.println("=======模板列表："+res);
        try {
            response.getWriter().write(res);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @RequestMapping("send")
    public void template(String openid,String orderno,HttpServletResponse response){
        String url="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        //openid="oHhZn0t6hpbFk5iaH1JXzDtvcoVg";
        String templateid="THQIUMKGquupwpz10DOu1zNTURU6f6aMWFyG41bJ4oI";
        String content=" {" +
                "           \"touser\":\""+openid+"\"," +
                "           \"template_id\":\"THQIUMKGquupwpz10DOu1zNTURU6f6aMWFyG41bJ4oI\"," +
                "           \"url\":\"http://weixin.qq.com/download\",  " +
                "           \"data\":{" +
                "                   \"orderno\": {" +
                "                       \"value\":\""+orderno+"\"," +
                "                       \"color\":\"#173177\"" +
                "                   }" +
                "           }" +
                "       }";

        String res=this.require(url,content);
        out.println("=======模板列表："+res);
        try {
            response.getWriter().write(res);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private String require(String url,String body){

        RequestBody b = RequestBody.create(MediaType.parse("application/json"), body);
        Request req = new Request.Builder()
                .url(url)
                .post(b)
                .build();
        try {
            Response res = client.newCall(req).execute();

            return res.body().string();
        }catch (IOException ex){
            ex.printStackTrace();
            return null;
        }
    }
    private String require(String url){

        Request req = new Request.Builder()
                .url(url)
                .build();
        try {
            Response res = client.newCall(req).execute();

            return res.body().string();
        }catch (IOException ex){
            ex.printStackTrace();
            return null;
        }
    }
}
